PROJECT_PATH = $(PWD)
APP_TARGET := "${PROJECT_PATH}/build/hschain"
APP_SRC := "hundsun.com/hsl/hschain/cmd/hschain"
CLI_TARGET := "${PROJECT_PATH}/build/hschain-cli"
CLI_SRC := "hundsun.com/hsl/hschain/cmd/cli"
BUILD_FLAGS = -ldflags "-X hundsun.com/hsl/hschain/common/version.GitCommit=`git rev-parse --short=8 HEAD`"
GENESIS_BLOCK_HELPER_TARGET := "${PROJECT_PATH}/build/genesisblockhelper"
GENESIS_BLOCK_HELPER_SRC := "hundsun.com/hsl/hschain/tools/genesisblockhelper"
KEY_STORE_HELPER_TARGET := "${PROJECT_PATH}/build/keystorehelper"
KEY_STORE_HELPER_SRC := "hundsun.com/hsl/hschain/tools/keystorehelper"

default: build

dep: ## Get the dependencies
	#@go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.41.0
	@go get -u golang.org/x/tools/cmd/goimports
	@go get -u github.com/mitchellh/gox
	@go get -u github.com/vektra/mockery/.../
	@go get -u mvdan.cc/sh/cmd/shfmt
	@go get -u mvdan.cc/sh/cmd/gosh


build: build_solo

solo: build_solo

dpos: build_dpos

solo_run: build_solo run_solo

dpos_run: build_dpos run_dpos

build_solo: clean build_main build_cli after_build solo_config

build_dpos: clean build_main build_cli after_build dpos_config

build_main:
	@cd cmd/hschain
	@go build $(BUILD_FLAGS) -i -v -o "${APP_TARGET}" ${APP_SRC}

build_cli:
	@cd cmd/cli
	@go build $(BUILD_FLAGS) -i -v -o $(CLI_TARGET) $(CLI_SRC)

after_build:
	@cp sampleconfig/solo-ecc/keystore-ecc-100.json build/keystore.json
	@cp cmd/contract-base-1.0.0-SNAPSHOT.jar build
	@mkdir -p build/config
	@cp cmd/*.yaml build/config

solo_config:
	@cp sampleconfig/solo-ecc/genesis_block_config.yaml build
	@./build/hschain-cli net generate --private build/private.key --public build/public.key
	@sed -i 's/peerIdPriKeyPath:.*/peerIdPriKeyPath: \"private.key\"/g' build/config/module_configs.yaml
	@sed -i 's/bootIdPubKeyPath:.*/bootIdPubKeyPath: \"public.key\"/g' build/config/module_configs.yaml
	@peer0=$$(./build/hschain-cli net show -p build/public.key | awk -F ' ' '{print $$4}'); echo "$${peer0}"; \
                sed -i 's/peerID: .*/peerID: '"$${peer0}"'/' build/genesis_block_config.yaml;
	@./build/hschain-cli genesis generate --input build/genesis_block_config.yaml --output build/genesis.block
	@sed -i 's/bootstrapPeers/#bootstrapPeers/g' build/config/module_configs.yaml

run_solo:
	@cd build/ && nohup ./hschain > hschain.log &

dpos_config:
	@mkdir node0 node1 node2
	@./build/hschain-cli net generate --private ./node0/private.key --public ./node0/public.key
	@./build/hschain-cli net generate --private ./node1/private.key --public ./node1/public.key
	@./build/hschain-cli net generate --private ./node2/private.key --public ./node2/public.key
	@cp sampleconfig/3miners-ecc/genesis_block_config.yaml build/genesis_block_config_dpos.yaml
	@sed -i 's/peerIdPriKeyPath:.*/peerIdPriKeyPath: \"private.key\"/g' build/config/module_configs.yaml
	@sed -i 's/bootIdPubKeyPath:.*/bootIdPubKeyPath: \"public.key\"/g' build/config/module_configs.yaml
	@peer0=$$(./build/hschain-cli net show -p node0/public.key | awk -F ' ' '{print $$4}'); echo "$${peer0}"; \
                sed -i '0,/peerID:.*/s/peerID: .*/peerID: '"$${peer0}"'/' build/genesis_block_config_dpos.yaml; \
                sed -i 's/peerID: QmbAU6WJieMNUN89BQ8s3kfcMHH2RUJL1VSSBUJ2WNyLKB/peerID: '"$${peer0}"'/' build/genesis_block_config_dpos.yaml;
	@peer1=$$(./build/hschain-cli net show -p node1/public.key | awk -F ' ' '{print $$4}'); echo "$${peer1}"; \
                sed -i 's/peerID: QmRrJRKfsgcWZVMKfVXzqKmAvuQiLFVnWv3hpNRQp9rKsp/peerID: '"$${peer1}"'/' build/genesis_block_config_dpos.yaml;
	@peer2=$$(./build/hschain-cli net show -p node2/public.key | awk -F ' ' '{print $$4}'); echo "$${peer2}"; \
                sed -i 's/peerID: QmVS14LYUnZCENZibcXPatqGYKX2R4aCq7gBzqroNmeDcU/peerID: '"$${peer2}"'/' build/genesis_block_config_dpos.yaml;
	@./build/hschain-cli genesis generate --input build/genesis_block_config_dpos.yaml --output build/genesis.block
	@cp node0/public.key node1
	@cp node0/public.key node2
	@cp -R build/* node0
	@cp -R build/* node1
	@cp -R build/* node2
	@rm -rf build/*
	@mv node0 node1 node2 build
	@sed -i 's/bootstrapPeers/#bootstrapPeers/g' build/node0/config/module_configs.yaml
	@sed -i 's/minerAddress: .*/minerAddress: f0e06ebc5d77b19851bee96d5fc45509cda2dadd/' build/node1/config/module_configs.yaml
	@sed -i 's/minerAddress: .*/minerAddress: e078efcb4ea5bda29efa3d95ead3a9d7f8953689/' build/node2/config/module_configs.yaml
	@sed -i 's/grpcPort: .*/grpcPort: "50010"/' build/node1/config/module_configs.yaml
	@sed -i 's/jsonRpcPort: .*/jsonRpcPort: "50011"/' build/node1/config/module_configs.yaml
	@sed -i 's/p2pPort: .*/p2pPort: "10021"/' build/node1/config/module_configs.yaml
	@sed -i 's/grpcPort: .*/grpcPort: "50020"/' build/node2/config/module_configs.yaml
	@sed -i 's/jsonRpcPort: .*/jsonRpcPort: "50021"/' build/node2/config/module_configs.yaml
	@sed -i 's/p2pPort: .*/p2pPort: "10022"/' build/node2/config/module_configs.yaml

run_dpos:
	@cd build/node0 && nohup ./hschain > hschain.log &
	@cd build/node1 && nohup ./hschain > hschain.log &
	@cd build/node2 && nohup ./hschain > hschain.log &

proto:protobuf

protobuf: ## Generate protbuf file of types package
	./scripts/compile_proto_all.sh 

clean:
	@rm -rf build

linter: ## Use gometalinter check code, ignore some unserious warning
	@./scripts/golinter.sh "filter" $${path}

linter_test: ## Use gometalinter check code, for local test
	@./scripts/golinter.sh "test" $${path}

shellcheck:
	@find . -name '*.sh' -not -path "./vendor/*" | grep -v "common/third" | grep -v ".pb.go" | grep -v "jvm.go/classfile" | \
             grep -v "jvm.go/native/box" | grep -v "jvm.go/native/java" | grep -v "jvm.go/module/" | xargs shellcheck

gosec:
	@golangci-lint  run --no-config --issues-exit-code=1  --deadline=2m --disable-all --enable=gosec --skip-dirs=commands

test:
	@bash ./scripts/ci.sh test $${path}

race:
	@bash ./scripts/ci.sh race $${path}

coverage:
	@bash ./scripts/ci.sh coverage $${path}

vet:
	@bash ./scripts/ci.sh vet $${path}

ineffassign:
	@bash ./scripts/ci.sh ineffassign $${path}

fmt: fmt_proto fmt_shell ## go fmt
	@find . -name '*.go' -not -path "./vendor/*" | grep -v "common/third" | \
              grep -v ".pb.go" | grep -v "jvm.go" | grep -v "evm/ext" | grep -v "evm/vm" | xargs gofmt -w -s
	@find . -name '*.go' -not -path "./vendor/*" | grep -v "common/third" | \
              grep -v ".pb.go" | grep -v "jvm.go" | grep -v "evm/ext" | grep -v "evm/vm" | xargs goimports -l -w

.PHONY: fmt_proto fmt_shell
fmt_proto: ## go fmt protobuf file
	#@find . -name '*.proto' -not -path "./vendor/*" | xargs clang-format -i

fmt_shell: ## check shell file
	@find . -name '*.sh' -not -path "./vendor/*" | grep -v "common/log" | grep -v "common/third" | grep -v ".pb.go" | grep -v "jvm.go/classfile" | \
        grep -v "jvm.go/native/box" | grep -v "jvm.go/native/java" | grep -v "jvm.go/module/" | xargs shfmt -w -s -i 4 -ci -bn

.PHONY: checkgofmt
checkgofmt: ## get all go files and run go fmt on them
	@files=$$(find . -name '*.go' -not -path "./vendor/*" | grep -v "common/log" | grep -v "common/third" | grep -v ".pb.go" | \
		  grep -v "jvm.go" | grep -v "evm/ext" | grep -v "evm/vm" | xargs gofmt -l); if [ -n "$$files" ]; then \
		  echo "Error: 'make fmt' needs to be run on:"; \
		  echo "$${files}"; \
		  exit 1; \
		  fi;
	@files=$$(find . -name '*.go' -not -path "./vendor/*" | grep -v "common/log" | grep -v "common/third" | grep -v ".pb.go" | \
		  grep -v "jvm.go" | grep -v "evm/ext" | grep -v "evm/vm" | xargs goimports -l); if [ -n "$$files" ]; then \
		  echo "Error: 'make fmt' needs to be run on:"; \
		  echo "$${files}"; \
		  exit 1; \
		  fi;

auto_fmt:
	if [ ! -d .git/hooks ]; then mkdir .git/hooks; fi && cp scripts/auto_fmt.sh .git/hooks/pre-commit

integration_test:
	@ginkgo -r --randomizeAllSpecs --randomizeSuites --failOnPending --cover --trace --race --progress
